Skip to content

Conversation

@transphorm
Copy link
Member

@transphorm transphorm commented Oct 15, 2025

Summary

  • add a selectResponsiveValues helper to useCompactLayout to compute multiple responsive values at once
  • update compact-aware screens and components to consume the helper for consistent sizing logic
  • simplify mnemonic spacing by reusing the shared selector instead of repeating inline calculations

Testing

  • not run (not requested)

https://chatgpt.com/codex/tasks/task_b_68eebf896864832d9480ccc839ea9595

Summary by CodeRabbit

  • New Features

    • Responsive/compact layouts across onboarding, recovery, documents, and shared screens with adaptive typography, spacing, and horizontal padding.
    • Safe-area aware top/bottom padding.
    • Dynamic sizing for icons, cards, and buttons.
    • Improved keyboard handling on “Recover with Phrase.”
    • Mnemonic display gains compact styling and refined copy/reveal button padding.
    • Disclaimer screen now navigates to Home after dismissing the privacy note.
  • Refactor

    • Replaced hard-coded paddings, margins, and font sizes with responsive values; restructured sections for flexibility.
  • Style

    • Visual polish for readability and consistency.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a new responsive layout hook and integrates it across multiple screens and components to compute padding, spacing, and typography based on device dimensions and safe-area insets. Several layouts switch to dynamic values; one screen reworks content into a KeyboardAvoidingView + ScrollView. Minor prop extensions and memoization added.

Changes

Cohort / File(s) Summary
Responsive hook (new)
app/src/hooks/useCompactLayout.ts
Adds a hook exposing compact state, responsive value selectors, and horizontal padding helpers; exports thresholds, types, and default function.
Mnemonic responsive updates
app/src/components/Mnemonic.tsx
Integrates useCompactLayout; adds compact rendering to WordPill prop/signature; applies responsive gaps/padding and button sizing; adjusts per-word typography.
Expandable bottom layout spacing
app/src/layouts/ExpandableBottomLayout.tsx
Computes responsive padding for TopSection/BottomSection; merges incoming styles with computed spacing.
Account recovery entry
app/src/screens/account/recovery/AccountRecoveryScreen.tsx
Applies responsive icon/text sizes and paddings; uses safe-area bottom inset for bottom padding; updates BottomSection paddings.
Recover with phrase UX
app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx
Replaces static YStack with KeyboardAvoidingView + ScrollView; dynamic TextArea minHeight; preserves paste and continue actions; adds flex container styles.
Launch screen responsiveness
app/src/screens/app/LaunchScreen.tsx
Replaces fixed card and typography sizes with responsive values; dynamic top/CTA paddings and spacing.
Documents selection: country
app/src/screens/documents/selection/CountryPickerScreen.tsx
Responsive heading/subheading sizes, vertical/section spacing, and horizontal padding via helper; replaces hard-coded values.
Documents selection: ID picker
app/src/screens/documents/selection/IDPickerScreen.tsx
Introduces responsive paddings and typography for hero, cards, descriptions, and helper text; adjusts section margins.
Onboarding: account verified
app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx
Adds safe-area-aware bottom padding; responsive gaps, margins, and text sizes; applies horizontal padding helper.
Onboarding: disclaimer
app/src/screens/onboarding/DisclaimerScreen.tsx
Responsive animation size and spacings; adjusts button margin; updates navigation flow to also route to Home after privacy note dismissal.
Onboarding: save phrase
app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx
Adds responsive paddings, gaps, and memoized title/description styles; replaces fixed typography metrics.
Shared: coming soon
app/src/screens/shared/ComingSoonScreen.tsx
Uses safe-area insets and responsive sizes for title/body and paddings; updates top margin and bottom section padding.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Screen as Screen Component
  participant Hook as useCompactLayout
  participant RN as React Native Dimensions
  participant SafeArea as Safe Area Insets

  Screen->>Hook: useCompactLayout(options)
  Hook->>RN: useWindowDimensions()
  Hook-->>Screen: { isCompact*, selectResponsiveValue(s), getResponsiveHorizontalPadding() }

  Screen->>SafeArea: useSafeAreaInsets()
  Screen->>Screen: Compute paddings, gaps, font sizes via selectors
  Screen->>UI: Render with responsive styles (padding, gap, fontSize)
  note over Screen,UI: Buttons, typography, and containers adapt to width/height

  alt Keyboard visible (RecoverWithPhrase)
    Screen->>UI: KeyboardAvoidingView + ScrollView layout
  else No keyboard
    Screen->>UI: Static YStack/BOTTOM sections with responsive padding
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Fix style prop shorthands #787 — Similar adjustments to ExpandableBottomLayout BottomSection padding/style merging; likely touches the same style calculation paths.

Suggested reviewers

  • aaronmgdr
  • shazarre

Poem

Screens that breathe with width and height,
Pill words slim down, snug and light.
Cards now flex, and buttons glide,
Insets cushion every side.
A gentle scroll when keys appear—
Responsive whispers: “We adapt here.” ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title succinctly conveys the primary change—refactoring to centralize responsive selectors via the new helper—and accurately reflects the content of the pull request without extraneous detail. It uses a clear “refactor:” prefix, is concise, and highlights the main objective of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/plan-for-dynamic-component-resizing-8a7079

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@transphorm transphorm changed the title refactor: centralize responsive selectors feat: improve layout on smaller screens Oct 15, 2025
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment on lines 77 to +80
styles.topSection,
roundTop && styles.roundTop,
roundTop ? { marginTop: top } : { paddingTop: top },
spacingStyle,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve safe-area padding in top sections

The new responsive padding in TopSection is applied after the safe-area padding (paddingTop: top). Because spacingStyle sets paddingVertical, it overwrites paddingTop, so screens that render ExpandableBottomLayout.TopSection without roundTop no longer include the safe area inset and their content will be rendered under the status bar on devices with a notch. Consider combining the safe-area value into the responsive padding instead of replacing it.

Useful? React with 👍 / 👎.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
app/src/layouts/ExpandableBottomLayout.tsx (1)

62-71: Consolidate useCompactLayout calls to avoid duplication.

Both TopSection and BottomSection independently call useCompactLayout({ compactHeight: 760 }) and create similar spacingStyle computations. This creates unnecessary duplication and could lead to inconsistencies if the threshold or spacing logic changes.

Consider computing the responsive values once at the parent ExpandableBottomLayout level and passing them down as props, or extract the spacing logic into a shared hook/constant.

Example consolidation:

+const useExpandableBottomSpacing = () => {
+  const { selectResponsiveValue } = useCompactLayout({
+    compactHeight: 760,
+  });
+  return useMemo(
+    () => ({
+      paddingHorizontal: selectResponsiveValue(16, 20, 'width'),
+      paddingVertical: selectResponsiveValue(16, 20, 'height'),
+      paddingTop: selectResponsiveValue(18, 30, 'height'),
+    }),
+    [selectResponsiveValue],
+  );
+};
+
 const TopSection: React.FC<TopSectionProps> = ({
   children,
   backgroundColor,
   ...props
 }) => {
   const { top } = useSafeAreaInsets();
   const { roundTop, style: incomingStyle, ...restProps } = props;
-  const { selectResponsiveValue } = useCompactLayout({
-    compactHeight: 760,
-  });
-  const spacingStyle = useMemo(
-    () => ({
-      paddingHorizontal: selectResponsiveValue(16, 20, 'width'),
-      paddingVertical: selectResponsiveValue(16, 20, 'height'),
-    }),
-    [selectResponsiveValue],
-  );
+  const spacing = useExpandableBottomSpacing();
+  const spacingStyle = {
+    paddingHorizontal: spacing.paddingHorizontal,
+    paddingVertical: spacing.paddingVertical,
+  };

Also applies to: 124-133

app/src/screens/app/LaunchScreen.tsx (1)

44-45: Document hardcoded layout multipliers.

Several magic numbers are used without explanation:

  • Line 44: screenWidth * 0.8 (80% of screen width) and max width of 320
  • Line 45: 180 / 300 aspect ratio (0.6) for card dimensions
  • Line 63: screenHeight * 0.08 (8% of screen height) for top padding

While the responsive approach using Math.min and Math.max provides safety bounds, these multipliers should be extracted as named constants with comments explaining the design rationale. This improves maintainability and makes it easier to adjust the layout if design requirements change.

Example:

+// Design system constants
+const CARD_WIDTH_PERCENT = 0.8; // 80% of screen width for optimal card presentation
+const CARD_MAX_WIDTH = 320; // Cap at 320px to prevent over-sizing on tablets
+const CARD_ASPECT_RATIO = 180 / 300; // Original design aspect ratio
+const TOP_PADDING_PERCENT = 0.08; // 8% of screen height
+
 const LaunchScreen: React.FC = () => {
   // ...
-  const cardWidth = Math.min(screenWidth * 0.8, 320);
-  const cardHeight = cardWidth * (180 / 300);
+  const cardWidth = Math.min(screenWidth * CARD_WIDTH_PERCENT, CARD_MAX_WIDTH);
+  const cardHeight = cardWidth * CARD_ASPECT_RATIO;
   // ...
-  const topPadding = Math.max(screenHeight * 0.08, baseTopPadding);
+  const topPadding = Math.max(screenHeight * TOP_PADDING_PERCENT, baseTopPadding);

Also applies to: 63-64

app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx (1)

54-56: Extract magic layout values into named constants and verify layout on all device sizes.

  • In RecoverWithPhraseScreen.tsx (line 56) and LaunchScreen.tsx (line 63), replace inline 160, 0.3, and 0.08 with descriptive constants (e.g. MIN_TEXTAREA_HEIGHT, TEXTAREA_HEIGHT_RATIO, TOP_PADDING_RATIO) and document their rationale.
  • Manually test the KeyboardAvoidingView + ScrollView layout on small, standard, and large devices to confirm the TextArea scales correctly.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3c5603 and a1457f6.

📒 Files selected for processing (12)
  • app/src/components/Mnemonic.tsx (5 hunks)
  • app/src/hooks/useCompactLayout.ts (1 hunks)
  • app/src/layouts/ExpandableBottomLayout.tsx (6 hunks)
  • app/src/screens/account/recovery/AccountRecoveryScreen.tsx (3 hunks)
  • app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx (4 hunks)
  • app/src/screens/app/LaunchScreen.tsx (5 hunks)
  • app/src/screens/documents/selection/CountryPickerScreen.tsx (6 hunks)
  • app/src/screens/documents/selection/IDPickerScreen.tsx (6 hunks)
  • app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx (4 hunks)
  • app/src/screens/onboarding/DisclaimerScreen.tsx (4 hunks)
  • app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx (4 hunks)
  • app/src/screens/shared/ComingSoonScreen.tsx (8 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,tsx,jsx,sol,nr}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,tsx,jsx,sol,nr}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/src/layouts/ExpandableBottomLayout.tsx
  • app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx
  • app/src/screens/account/recovery/AccountRecoveryScreen.tsx
  • app/src/components/Mnemonic.tsx
  • app/src/screens/onboarding/DisclaimerScreen.tsx
  • app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx
  • app/src/screens/documents/selection/CountryPickerScreen.tsx
  • app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx
  • app/src/screens/app/LaunchScreen.tsx
  • app/src/screens/documents/selection/IDPickerScreen.tsx
  • app/src/hooks/useCompactLayout.ts
  • app/src/screens/shared/ComingSoonScreen.tsx
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Type checking must pass before PRs (yarn types)

Files:

  • app/src/layouts/ExpandableBottomLayout.tsx
  • app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx
  • app/src/screens/account/recovery/AccountRecoveryScreen.tsx
  • app/src/components/Mnemonic.tsx
  • app/src/screens/onboarding/DisclaimerScreen.tsx
  • app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx
  • app/src/screens/documents/selection/CountryPickerScreen.tsx
  • app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx
  • app/src/screens/app/LaunchScreen.tsx
  • app/src/screens/documents/selection/IDPickerScreen.tsx
  • app/src/hooks/useCompactLayout.ts
  • app/src/screens/shared/ComingSoonScreen.tsx
app/src/**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:

  • Component architecture and reusability
  • State management patterns
  • Performance optimizations
  • TypeScript type safety
  • React hooks usage and dependencies
  • Navigation patterns

Files:

  • app/src/layouts/ExpandableBottomLayout.tsx
  • app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx
  • app/src/screens/account/recovery/AccountRecoveryScreen.tsx
  • app/src/components/Mnemonic.tsx
  • app/src/screens/onboarding/DisclaimerScreen.tsx
  • app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx
  • app/src/screens/documents/selection/CountryPickerScreen.tsx
  • app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx
  • app/src/screens/app/LaunchScreen.tsx
  • app/src/screens/documents/selection/IDPickerScreen.tsx
  • app/src/hooks/useCompactLayout.ts
  • app/src/screens/shared/ComingSoonScreen.tsx
🧬 Code graph analysis (10)
app/src/screens/onboarding/AccountVerifiedSuccessScreen.tsx (3)
app/src/mocks/react-native-safe-area-context.js (1)
  • useSafeAreaInsets (44-46)
packages/mobile-sdk-alpha/src/constants/colors.ts (1)
  • white (59-59)
packages/mobile-sdk-alpha/src/components/typography/Title.tsx (1)
  • Title (18-41)
app/src/screens/account/recovery/AccountRecoveryScreen.tsx (2)
app/src/mocks/react-native-safe-area-context.js (1)
  • useSafeAreaInsets (44-46)
packages/mobile-sdk-alpha/src/components/typography/Title.tsx (1)
  • Title (18-41)
app/src/components/Mnemonic.tsx (1)
packages/mobile-sdk-alpha/src/constants/colors.ts (3)
  • slate300 (37-37)
  • white (59-59)
  • slate500 (43-43)
app/src/screens/onboarding/DisclaimerScreen.tsx (1)
app/src/screens/verification/ProofRequestStatusScreen.tsx (1)
  • styles (326-342)
app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx (1)
packages/mobile-sdk-alpha/src/components/typography/Title.tsx (1)
  • Title (18-41)
app/src/screens/documents/selection/CountryPickerScreen.tsx (4)
packages/mobile-sdk-alpha/src/components/layout/YStack.tsx (1)
  • YStack (10-12)
packages/mobile-sdk-alpha/src/components/typography/BodyText.tsx (1)
  • BodyText (12-14)
packages/mobile-sdk-alpha/src/utils/fonts.ts (2)
  • advercase (7-7)
  • dinot (8-8)
packages/mobile-sdk-alpha/src/constants/colors.ts (2)
  • slate500 (43-43)
  • black (8-8)
app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx (2)
app/src/mocks/react-native-safe-area-context.js (1)
  • useSafeAreaInsets (44-46)
packages/mobile-sdk-demo/tests/mocks/react-native.ts (1)
  • Platform (14-25)
app/src/screens/app/LaunchScreen.tsx (1)
app/src/mocks/react-native-gesture-handler.ts (1)
  • GestureDetector (45-50)
app/src/screens/documents/selection/IDPickerScreen.tsx (5)
app/src/components/NavBar/DocumentFlowNavBar.tsx (1)
  • DocumentFlowNavBar (14-46)
packages/mobile-sdk-alpha/src/components/layout/YStack.tsx (1)
  • YStack (10-12)
packages/mobile-sdk-alpha/src/utils/fonts.ts (1)
  • dinot (8-8)
packages/mobile-sdk-alpha/src/constants/colors.ts (1)
  • black (8-8)
packages/mobile-sdk-alpha/src/components/typography/BodyText.tsx (1)
  • BodyText (12-14)
app/src/screens/shared/ComingSoonScreen.tsx (1)
app/src/mocks/react-native-safe-area-context.js (1)
  • useSafeAreaInsets (44-46)
🪛 GitHub Actions: Workspace CI
app/src/components/Mnemonic.tsx

[error] 5-5: simple-import-sort/imports: Run autofix to sort these imports!

🪛 GitHub Check: workspace-lint
app/src/layouts/ExpandableBottomLayout.tsx

[failure] 5-5:
Run autofix to sort these imports!

app/src/screens/account/recovery/AccountRecoveryScreen.tsx

[warning] 30-30:
Insert ⏎···


[warning] 83-83:
Replace ·gap={buttonStackGap}·width="100%"·paddingTop={buttonPaddingTop} with ⏎············gap={buttonStackGap}⏎············width="100%"⏎············paddingTop={buttonPaddingTop}⏎··········

app/src/components/Mnemonic.tsx

[failure] 5-5:
Run autofix to sort these imports!


[warning] 115-115:
Replace ⏎············key={i}⏎············word={word}⏎············index={i}⏎············compact={isCompactWidth}⏎········· with ·key={i}·word={word}·index={i}·compact={isCompactWidth}

app/src/screens/onboarding/SaveRecoveryPhraseScreen.tsx

[failure] 5-5:
Run autofix to sort these imports!

app/src/screens/account/recovery/RecoverWithPhraseScreen.tsx

[warning] 132-132:
Replace ⏎··········styles.layout,⏎··········{·paddingBottom:·bottom·+·24·},⏎········ with styles.layout,·{·paddingBottom:·bottom·+·24·}

app/src/hooks/useCompactLayout.ts

[warning] 86-86:
Replace infer·TValue with ⏎··········infer·TValue⏎········


[warning] 84-84:
Delete ]


[warning] 82-82:
Replace keyof·TConfig,⏎········ResponsiveValueConfig<unknown>, with [keyof·TConfig,·ResponsiveValueConfig<unknown>]


[warning] 81-81:
Delete [


[warning] 50-50:
Replace options?:·ResponsivePaddingOptions with ⏎····options?:·ResponsivePaddingOptions,⏎··


[warning] 43-43:
Replace TConfig·extends·Record<string,·ResponsiveValueConfig<unknown>> with ⏎····TConfig·extends·Record<string,·ResponsiveValueConfig<unknown>>,⏎··


[failure] 9-9:
Expected DEFAULT_COMPACT_HEIGHT before DEFAULT_COMPACT_WIDTH

⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: android-build-test
  • GitHub Check: e2e-ios
  • GitHub Check: analyze-ios
  • GitHub Check: analyze-android
  • GitHub Check: build-deps
🔇 Additional comments (1)
app/src/screens/account/recovery/AccountRecoveryScreen.tsx (1)

42-51: Omitting dimension is valid for selectResponsiveValues. The hook defaults dimension to 'any', applying the compact layout when either width or height is compact. No changes needed.

Likely an incorrect or invalid review comment.

Comment on lines 44 to 48
{index}
</Text>
<Text color={slate500} fontSize={14} fontWeight={500}>
<Text color={slate500} fontSize={compact ? 13 : 14} fontWeight={500}>
{word}
</Text>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix mnemonic numbering regression

Line 44 renders {index}, but the list now passes index={i} (Lines 115-121), so the first pill shows 0 instead of 1. That’s a user-visible correctness bug. Display index + 1 (or pass i + 1) before rendering.

-      <Text color={slate300} fontSize={compact ? 13 : 14} fontWeight={500}>
-        {index}
+      <Text color={slate300} fontSize={compact ? 13 : 14} fontWeight={500}>
+        {index + 1}

Also applies to: 115-121

🤖 Prompt for AI Agents
In app/src/components/Mnemonic.tsx around lines 44 to 48 (and similarly where
the list passes index at lines 115-121), the component renders the zero-based
`index` which displays "0" for the first mnemonic; change the displayed value to
`index + 1` (or alternatively pass `i + 1` from the parent) so numbering starts
at 1, and update the list invocation at lines 115-121 to pass a 1-based index if
you choose that approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants